using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection.Emit;
using System.Text;
using RaisingStudio.SmallBasicCompiler.Completion;
using RaisingStudio.SmallBasicCompiler.Expressions;

namespace RaisingStudio.SmallBasicCompiler.Statements
{
    public class IfStatement : Statement
    {
        public List<Statement> ThenStatements = new List<Statement>();
        public List<Statement> ElseIfStatements = new List<Statement>();
        public List<Statement> ElseStatements = new List<Statement>();
        public Expression Condition;
        public TokenInfo IfToken;
        public TokenInfo ThenToken;
        public TokenInfo ElseToken;
        public TokenInfo EndIfToken;
        public override void AddSymbols(SymbolTable symbolTable)
        {
            if (this.Condition != null)
            {
                this.Condition.AddSymbols(symbolTable);
            }
            foreach (Statement current in this.ThenStatements)
            {
                current.AddSymbols(symbolTable);
            }
            foreach (Statement current2 in this.ElseIfStatements)
            {
                current2.AddSymbols(symbolTable);
            }
            foreach (Statement current3 in this.ElseStatements)
            {
                current3.AddSymbols(symbolTable);
            }
        }
        public override void PrepareForEmit(CodeGenScope scope)
        {
            foreach (Statement current in this.ThenStatements)
            {
                current.PrepareForEmit(scope);
            }
            foreach (Statement current2 in this.ElseIfStatements)
            {
                current2.PrepareForEmit(scope);
            }
            foreach (Statement current3 in this.ElseStatements)
            {
                current3.PrepareForEmit(scope);
            }
        }
        public override void EmitIL(CodeGenScope scope)
        {
            Label label = scope.ILGenerator.DefineLabel();
            Label label2 = scope.ILGenerator.DefineLabel();
            this.Condition.EmitIL(scope);
            scope.ILGenerator.EmitCall(OpCodes.Call, scope.TypeInfoBag.PrimitiveToBoolean, null);
            scope.ILGenerator.Emit(OpCodes.Brfalse, label2);
            foreach (Statement current in this.ThenStatements)
            {
                current.EmitIL(scope);
            }
            scope.ILGenerator.Emit(OpCodes.Br, label);
            using (List<Statement>.Enumerator enumerator2 = this.ElseIfStatements.GetEnumerator())
            {
                while (enumerator2.MoveNext())
                {
                    ElseIfStatement elseIfStatement = (ElseIfStatement)enumerator2.Current;
                    scope.ILGenerator.MarkLabel(label2);
                    label2 = scope.ILGenerator.DefineLabel();
                    elseIfStatement.Condition.EmitIL(scope);
                    scope.ILGenerator.EmitCall(OpCodes.Call, scope.TypeInfoBag.PrimitiveToBoolean, null);
                    scope.ILGenerator.Emit(OpCodes.Brfalse, label2);
                    foreach (Statement current2 in elseIfStatement.ThenStatements)
                    {
                        current2.EmitIL(scope);
                    }
                    scope.ILGenerator.Emit(OpCodes.Br, label);
                }
            }
            scope.ILGenerator.MarkLabel(label2);
            foreach (Statement current3 in this.ElseStatements)
            {
                current3.EmitIL(scope);
            }
            scope.ILGenerator.MarkLabel(label);
        }
        public override void PopulateCompletionItems(CompletionBag completionBag, int line, int column, bool globalScope)
        {
            if (base.StartToken.Line == line)
            {
                if (column < this.IfToken.EndColumn)
                {
                    CompletionHelper.FillAllGlobalItems(completionBag, globalScope);
                    return;
                }
                CompletionHelper.FillLogicalExpressionItems(completionBag);
                CompletionHelper.FillKeywords(completionBag, new Token[]
				{
					Token.Then
				});
                return;
            }
            else
            {
                if (line == this.ElseToken.Line)
                {
                    CompletionHelper.FillKeywords(completionBag, new Token[]
					{
						Token.Else, 
						Token.EndIf
					});
                    CompletionHelper.FillAllGlobalItems(completionBag, false);
                    return;
                }
                if (line == this.EndIfToken.Line)
                {
                    CompletionHelper.FillKeywords(completionBag, new Token[]
					{
						Token.EndIf
					});
                    CompletionHelper.FillAllGlobalItems(completionBag, false);
                    return;
                }
                Statement statementContaining = Statement.GetStatementContaining(this.ElseStatements, line);
                CompletionHelper.FillKeywords(completionBag, new Token[]
				{
					Token.EndIf
				});
                if (statementContaining == null)
                {
                    CompletionHelper.FillKeywords(completionBag, new Token[]
					{
						Token.Else
					});
                    statementContaining = Statement.GetStatementContaining(this.ElseIfStatements, line);
                    if (statementContaining == null)
                    {
                        CompletionHelper.FillKeywords(completionBag, new Token[]
						{
							Token.ElseIf
						});
                        statementContaining = Statement.GetStatementContaining(this.ThenStatements, line);
                    }
                }
                if (statementContaining != null)
                {
                    statementContaining.PopulateCompletionItems(completionBag, line, column, false);
                }
                return;
            }
        }
        public override int GetIndentationLevel(int line)
        {
            if (line == this.IfToken.Line)
            {
                return 0;
            }
            if (this.ElseToken.Token != Token.Illegal && line == this.ElseToken.Line)
            {
                return 0;
            }
            if (this.EndIfToken.Token != Token.Illegal && line == this.EndIfToken.Line)
            {
                return 0;
            }
            Statement statementContaining = Statement.GetStatementContaining(this.ElseStatements, line);
            if (statementContaining != null)
            {
                return 1 + statementContaining.GetIndentationLevel(line);
            }
            statementContaining = Statement.GetStatementContaining(this.ElseIfStatements, line);
            if (statementContaining != null)
            {
                return statementContaining.GetIndentationLevel(line);
            }
            statementContaining = Statement.GetStatementContaining(this.ThenStatements, line);
            if (statementContaining != null)
            {
                return 1 + statementContaining.GetIndentationLevel(line);
            }
            return 1;
        }
        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.AppendFormat(CultureInfo.CurrentUICulture, "{0} {1} {2}\r\n", new object[]
			{
				this.IfToken.Text, 
				this.Condition, 
				this.ThenToken.Text
			});
            foreach (Statement current in this.ThenStatements)
            {
                stringBuilder.AppendFormat(CultureInfo.CurrentUICulture, "  {0}", new object[]
				{
					current
				});
            }
            foreach (Statement current2 in this.ElseIfStatements)
            {
                stringBuilder.AppendFormat(CultureInfo.CurrentUICulture, "  {0}", new object[]
				{
					current2
				});
            }
            if (this.ElseToken.TokenType != TokenType.Illegal)
            {
                stringBuilder.AppendFormat(CultureInfo.CurrentUICulture, "{0}\r\n", new object[]
				{
					this.ElseToken.Text
				});
                foreach (Statement current3 in this.ElseStatements)
                {
                    stringBuilder.AppendFormat(CultureInfo.CurrentUICulture, "  {0}", new object[]
					{
						current3
					});
                }
            }
            stringBuilder.AppendFormat(CultureInfo.CurrentUICulture, "{0}\r\n", new object[]
			{
				this.EndIfToken.Text
			});
            return stringBuilder.ToString();
        }
    }
}
